package com.cgy.utils.base.strings;

import com.cgy.utils.base.constant.CommonConstant;
import com.cgy.utils.base.list.ListHelper;
import com.cgy.utils.base.map.MapHelper;
import com.google.common.base.Splitter;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.cgy.utils.base.constant.Strings.*;

/**
 * string 工具类
 * 
 * @author CHTK
 */
public class StringHelper {

	/**
	 * 为空
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isEmpty(final String value) {
		return null == value;
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isAnyEmpty(final String... value) {
		if (null == value) {
			return true;
		}
		for (String s : value) {
			if (isEmpty(s)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isNotEmpty(final String value) {
		return !isEmpty(value);
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isAnyNotEmpty(final String... value) {
		if (null == value) {
			return false;
		}

		for (String s : value) {
			if (isEmpty(s)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isBlank(final String value) {
		return null == value || EMPTY.equals(value.trim());
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @param stringElseHandler
	 * @return
	 */
	public static void isBlank(final String value, final StringElseHandler stringElseHandler) {
		if (isBlank(value) && null != stringElseHandler) {
			stringElseHandler.handler(value);
		}
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @param stringElseHandler
	 * @return
	 */
	public static void isBlank(final String value, final StringIfNotBlankHandler stringIfNotBlankHandler,
			final StringElseHandler stringElseHandler) {
		if (isBlank(value) && null != stringElseHandler) {
			stringElseHandler.handler(value);
		} else if (null != stringIfNotBlankHandler) {
			stringIfNotBlankHandler.handler(value);
		}
	}

	/**
	 * 不为空
	 * 
	 * @param value
	 * @param stringIfNotBlankHandler
	 * @return
	 */
	public static void isNotBlank(final String value, final StringIfNotBlankHandler stringIfNotBlankHandler,
			final StringElseHandler stringElseHandler) {
		if (isNotBlank(value) && null != stringIfNotBlankHandler) {
			stringIfNotBlankHandler.handler(value);
		} else if (null != stringElseHandler) {
			stringElseHandler.handler(value);
		}
	}

	/**
	 * 不为空
	 * 
	 * @param value
	 * @param stringIfNotBlankHandler
	 * @return
	 */
	public static void isNotBlank(final String value, final StringIfNotBlankHandler stringIfNotBlankHandler) {
		if (isNotBlank(value) && null != stringIfNotBlankHandler) {
			stringIfNotBlankHandler.handler(value);
		}
	}

	/**
	 * 不为空
	 * 
	 * @param emptyHandler
	 * @param values
	 * @return
	 */
	public static void isAnyNotBlank(final AnyEmptyHandler emptyHandler, final String... values) {
		if (null != values && null != emptyHandler) {
			for (String value : values) {
				if (isBlank(value)) {
					return;
				}
			}
			emptyHandler.handler(values.length, values);
		}
	}

	/**
	 * 转为字符串
	 * 
	 * @param value
	 * @return
	 */
	public static String toString(final String value) {
		return isBlank(value) ? EMPTY : value.toString();
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isAnyBlank(final String... value) {
		if (null == value) {
			return true;
		}
		for (String s : value) {
			if (isBlank(s)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isNotBlank(final String value) {
		return !isBlank(value);
	}

	/**
	 * 为空
	 * 
	 * @param value
	 * @return
	 */
	public static boolean isAnyNotBlank(final String... value) {
		if (null == value) {
			return false;
		}

		for (String s : value) {
			if (isBlank(s)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 获取字符串之间值
	 * 
	 * @param start
	 * @param end
	 * @param srcValue 源数据
	 * @return
	 */
	public static final List<String> cut(final String srcValue, final String start, final String end) {
		return pattern(srcValue, start + REGEXP_ALL + end, -1);
	}

	/**
	 *
	 * @param start
	 * @param srcValue 源数据
	 * @param limit
	 * @return
	 */
	public static final List<String> startsWith(final String srcValue, final String start, int limit) {
		return pattern(srcValue, start + REGEXP_ALL, limit);
	}

	/**
	 *
	 * @param start
	 * @param srcValue 源数据
	 * @return
	 */
	public static final List<String> startsWith(final String srcValue, final String start) {
		return pattern(srcValue, start + REGEXP_ALL, -1);
	}

	/**
	 *
	 * @param start
	 * @param srcValue 源数据
	 * @return
	 */
	public static final String startsWithString(final String srcValue, final String start) {
		return ListHelper.only(pattern(srcValue, start + REGEXP_ALL, 1));
	}

	/**
	 *
	 * @param end
	 * @param srcValue 源数据
	 * @return
	 */
	public static final List<String> endsWith(final String srcValue, final String end, final int limit) {
		return pattern(srcValue, REGEXP_ALL + end, limit);
	}

	/**
	 *
	 * @param end
	 * @param srcValue 源数据
	 * @return
	 */
	public static final List<String> endsWith(final String srcValue, final String end) {
		return pattern(srcValue, REGEXP_ALL + end, -1);
	}

	/**
	 *
	 * @param end
	 * @param srcValue 源数据
	 * @return
	 */
	public static final String endsWithString(final String srcValue, final String end) {
		final List<String> pattern = pattern(srcValue, REGEXP_ALL + end, 1);
		return ListHelper.one(pattern);
	}

	/**
	 * 正则匹配
	 * 
	 * @param srcValue     源数据
	 * @param patternValue
	 * @return
	 */
	public static final List<String> pattern(final String srcValue, final String patternValue, final int limit) {
		return pattern(srcValue, patternValue, limit, new PatternHandler() {

			@Override
			public String group(Matcher matcher) {
				return matcher.group(1);
			}
		});
	}

	/**
	 * 正则匹配
	 * 
	 * @param srcValue     源数据
	 * @param patternValue
	 * @return
	 */
	public static final List<String> pattern(final String srcValue, final String patternValue, final int limit,
			PatternHandler patternHandler) {
		Pattern pattern = Pattern.compile(patternValue);
		Matcher matcher = pattern.matcher(srcValue);

		List<String> lStrings = new ArrayList<>();
		while (matcher.find()) {
			final String group = patternHandler.group(matcher);
			if (-1 == limit || lStrings.size() <= limit) {
				lStrings.add(null != group ? group.trim() : EMPTY);
			} else {
				break;
			}
		}
		return lStrings;
	}

	/**
	 * 拆分字段
	 * 
	 * @param srcValue  源数据
	 * @param condition
	 * @return
	 */
	public static List<String> splitters(String srcValue, String... condition) {
		if (isEmpty(srcValue)) {
			return ListHelper.newArrayList();
		}
		String regex = EMPTY;
		for (String s : condition) {
			regex += EXTENSION_OR + s;
		}
		if (regex.length() > 0) {
			regex = regex.substring(1);
		}

		return Splitter.onPattern(regex).omitEmptyStrings().splitToList(srcValue);
	}

	/**
	 * 获取前缀
	 * 
	 * @param srcValue
	 * @param condition
	 * @param defautValue
	 * @return
	 */
	public static String preffix(String srcValue, String condition, String defautValue) {
		if (isEmpty(srcValue)) {
			return defautValue;
		}
		final String s = endsWithString(srcValue, condition);
		List<String> strings = Splitter.onPattern(REGEXP_EMPTY).trimResults().splitToList(s);
		String endValue = strings.get(strings.size() - 1);
		return isEmpty(endValue) ? defautValue : endValue;
	}

	/**
	 * 获取前缀
	 * 
	 * @param srcValue  源数据
	 * @param condition
	 */
	public static final String preffix(String srcValue, String condition) {
		return preffix(srcValue, condition, EMPTY);
	}

	/**
	 * 删除多余字符
	 * 
	 * @param con
	 * @param extensionPer
	 * @return
	 */
	public static String remove(String con, String extensionPer) {
		return con.replace(extensionPer, EMPTY);
	}

	/**
	 * 转为字符串
	 * 
	 * @param data
	 * @return
	 */
	public static String asString(byte[] data) {
		return new String(data, Charset.forName(UTF_8));
	}

	/**
	 * 转为List
	 * 
	 * @param data
	 * @return
	 */
	public static List<String> asList(byte[] data, final String separator) {
		String s = new String(data, Charset.forName(UTF_8));
		return Splitter.on(separator).trimResults().splitToList(s);
	}

	/**
	 * 去除空格
	 * 
	 * @param s
	 * @return
	 */
	public static String trim(final String s) {
		return isBlank(s) ? EMPTY : s.trim();
	}

	/**
	 * 将字符编码转换成US-ASCII码
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String toASCII(String str) throws UnsupportedEncodingException {
		return changeCharset(str, CommonConstant.Charset.US_ASCII);
	}

	/**
	 * 将字符编码转换成ISO-8859-1码
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String toISO_8859_1(String str) throws UnsupportedEncodingException {
		return changeCharset(str, CommonConstant.Charset.ISO_8859_1);
	}

	/**
	 * 将字符编码转换成UTF-8码
	 */
	public static String toUTF_8(String str) throws UnsupportedEncodingException {
		return changeCharset(str, CommonConstant.Charset.UTF_8);
	}

	/**
	 * 将字符编码转换成UTF-16BE码
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String toUTF_16BE(String str) throws UnsupportedEncodingException {
		return changeCharset(str, CommonConstant.Charset.UTF_16BE);
	}

	/**
	 * 将字符编码转换成UTF-16LE码
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String toUTF_16LE(String str) throws UnsupportedEncodingException {
		return changeCharset(str, CommonConstant.Charset.UTF_16LE);
	}

	/**
	 * 将字符编码转换成UTF-16码
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String toUTF_16(String str) throws UnsupportedEncodingException {
		return changeCharset(str, CommonConstant.Charset.UTF_16);
	}

	/**
	 * 将字符编码转换成GBK码
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String toGBK(String str) throws UnsupportedEncodingException {
		return changeCharset(str, CommonConstant.Charset.GBK);
	}

	/**
	 * 字符串编码转换的实现方法
	 *
	 * @param str        待转换编码的字符串
	 * @param newCharset 目标编码
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String changeCharset(String str, String newCharset) throws UnsupportedEncodingException {
		if (str != null) {
			// 用默认字符编码解码字符串。
			byte[] bs = str.getBytes();
			// 用新的字符编码生成字符串
			return new String(bs, newCharset);
		}
		return null;
	}

	/**
	 *
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String getDefaultCharSet() throws UnsupportedEncodingException {
		OutputStreamWriter writer = new OutputStreamWriter(new ByteArrayOutputStream(), CommonConstant.Charset.UTF_8);
		String enc = writer.getEncoding();
		return enc;
	}

	/**
	 * 字符串编码转换的实现方法
	 *
	 * @param str        待转换编码的字符串
	 * @param oldCharset 原编码
	 * @param newCharset 目标编码
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public final static String changeCharset(String str, String oldCharset, String newCharset)
			throws UnsupportedEncodingException {
		if (str != null) {
			// 用旧的字符编码解码字符串。解码可能会出现异常。
			byte[] bs = str.getBytes(oldCharset);
			// 用新的字符编码生成字符串
			return new String(bs, newCharset);
		}
		return null;
	}

	/**
	 * Unicode转换成GBK字符集
	 *
	 * @param input 待转换字符串
	 * @return 转换完成字符串
	 */
	public final static String toGBKWithUTF8(String input) throws UnsupportedEncodingException {
		if (isEmpty(input)) {
			return "";
		} else {
			String s1;
			s1 = new String(input.getBytes(CommonConstant.Charset.ISO_8859_1), CommonConstant.Charset.GBK);
			return s1;
		}
	}

	/**
	 * GBK转换成Unicode字符集
	 *
	 * @param input 待转换字符串
	 * @return 转换完成字符串
	 */
	public final static String toUnicodeWithGBK(String input) throws UnsupportedEncodingException {
		if (isEmpty(input)) {
			return "";
		} else {
			String s1;
			s1 = new String(input.getBytes(CommonConstant.Charset.GBK), CommonConstant.Charset.ISO_8859_1);
			return s1;
		}
	}

	/**
	 * 获取默认值
	 * 
	 * @param source
	 * @param defaultValue
	 * @return
	 */
	public static String getDefaultValue(final String source, final String defaultValue) {
		return isBlank(source) ? defaultValue : source;
	}

	/**
	 * 占位符处理
	 * 
	 * @param value 包含占位符
	 * @param data  数据
	 * @return
	 */
	public static String matcher(String value, final Map<String, Object> data, final String start, final String end) {
		if (StringUtils.isBlank(value)) {
			return value;
		}
		int startIndex = value.indexOf(start);
		if (startIndex > -1 && value.indexOf(end, startIndex) > -1) {
			String patternStr = FILE_RIGHT_SLASH + start + REGEXP_ALL_1 + FILE_RIGHT_SLASH + end;
			Pattern pattern = Pattern.compile(patternStr);
			Matcher matcher = pattern.matcher(value);
			while (matcher.find()) {
				String group = matcher.group();
				value = value.replace(group,
						MapHelper.strings(data, group.replace(start, EMPTY).replace(end, EMPTY), EMPTY));
			}

		}
		return value;
	}

	/**
	 * 获取字符串最后一节
	 * 
	 * @param name
	 * @return
	 */
	public static String lastEnd(final String name, final String... extensions) {
		if (isNotBlank(name)) {
			String extension = EXTENSION_REG_DOT;
			if (null != extensions && extensions.length > 0) {
				extension = extensions[0];
			}
			int index = name.lastIndexOf(extension);
			return index > -1 ? name.substring(0, index) : name;
		}
		return name;
	}

	/**
	 * 获取字符串前面一节
	 * 
	 * @param name
	 * @return
	 */
	public static String firstEnd(final String name, final String... extensions) {
		if (isNotBlank(name)) {
			String extension = EXTENSION_REG_DOT;
			if (null != extensions && extensions.length > 0) {
				extension = extensions[0];
			}
			int index = name.indexOf(extension);
			return index > -1 ? name.substring(index + 1) : name;
		}
		return name;
	}

	/**
	 *
	 * @param parameter
	 * @param header
	 * @param attribute
	 * @return
	 */
	public static String getNotBlank(String parameter, String header, String attribute) {
		if (isNotEmpty(parameter)) {
			return parameter;
		}
		if (isNotEmpty(header)) {
			return header;
		}
		if (isNotEmpty(attribute)) {
			return attribute;
		}
		return null;
	}

	/**
	 * 
	 * @param key
	 * @param signs
	 * @return
	 */
	public static boolean anyContains(String key, String... signs) {
		boolean isContains = false;
		if (isBlank(key) || null == signs || signs.length == 0) {
			return isContains;
		}
		for (String string : signs) {
			isContains = isContains || key.contains(string);
		}
		return isContains;
	}
	/**
	 * 
	 * @param key
	 * @param signs
	 * @return
	 */
	public static boolean allContains(String key, String... signs) {
		boolean isContains = true;
		if (isBlank(key) || null == signs || signs.length == 0) {
			return !isContains;
		}
		for (String string : signs) {
			isContains = isContains && key.contains(string);
		}
		return isContains;
	}
	/**
	 * 
	 * @param key
	 * @param signs
	 * @return
	 */
	public static boolean firstAndEndContains(String key, String... signs) {
		boolean isContains = true;
		if (isBlank(key) || null == signs || signs.length == 0) {
			return !isContains;
		}
		String first = key.substring(0, 1);
		String end = key.substring(key.length() - 1);
		
		return ArrayUtils.contains(signs, first) && ArrayUtils.contains(signs, end) ;
	}
	/**
	 * 
	 * @param key
	 * @param signs
	 * @return
	 */
	public static boolean firstOrEndContains(String key, String... signs) {
		boolean isContains = true;
		if (isBlank(key) || null == signs || signs.length == 0) {
			return !isContains;
		}
		String first = key.substring(0, 1);
		String end = key.substring(key.length() - 1);
		
		return ArrayUtils.contains(signs, first) || ArrayUtils.contains(signs, end) ;
	}

	/**
	 * 字符串为空处理
	 */
	public static interface StringElseHandler {

		/**
		 * 回调
		 * 
		 * @param value
		 * @return
		 */
		public String handler(String value);
	}

	/**
	 * 字符串不为空处理
	 */
	public static interface StringIfNotBlankHandler {

		/**
		 * 回调
		 * 
		 * @param value
		 * @return
		 */
		public void handler(String value);
	}

	/**
	 *
	 */
	public static interface AnyEmptyHandler {

		/**
		 * 回调
		 * 
		 * @param size
		 * @param value
		 * @return
		 */
		public void handler(int size, String... value);
	}

	/**
	 * 正则处理
	 * 
	 * @author Administrator
	 */
	public static interface PatternHandler {
		/**
		 *
		 * @param matcher
		 * @return
		 */
		public String group(Matcher matcher);
	}

}
